<template>
  <div>
    <!-- <el-button type="button" @click="saveImg">保存为图片</el-button>
    <el-button type="button" @click="print">打印</el-button> -->
    <div class="dashboard-container" style="width: 100vw;height: 100vh; display: fixed; justify-content: space-between">
      <!-- <div class="dashboard-text">name: {{ name }}</div>
      <div>ZooMze</div>
      <div class="dashboard-text">roles: <span v-for="role in roles" :key="role">{{ role }}</span></div> -->
      <!-- <div id="myPaletteDiv" style="width: 100px; margin-right: 2px; background-color: #282c34;"></div> -->
      <div id="myDiagramDiv" style="flex-grow: 1; height: 100vh; width: 100vw; background-color: #fff;"></div>
    </div>
    <van-popup v-model="show">
      <h4>{{ flowName }}</h4>
      <div v-for="item in nodeData">
        <p>主办人: {{ item.flowuser }}</p>
        <p v-if="item.pertype != '0' && item.pertype != '4' && item.pertype != '9'">时间: {{ item.approvaldate }}</p>
        <p>审批类型: {{ item.perText }}</p>
        <p v-if="item.pertype == 6">被委托人: {{ item.entrust }}</p>
        <p v-if="item.pertype == 8">会签人: {{ item.act }}</p>
        <p v-if="item.pertype == '1' || item.pertype == '2' || item.pertype == '3'|| item.pertype == '5'|| item.pertype == '6'">签批意见:</p>
        <p v-if="item.pertype == '1' || item.pertype == '2' || item.pertype == '3'|| item.pertype == '5'|| item.pertype == '6'">{{ item.lnstructions || '无' }}</p><br v-if="nodeData.length > 0"/>
      </div>
    </van-popup>
  </div>
</template>

<script>
  import * as go from "../../node_modules/gojs/release/go-module.js";
  export default {
    data() {
      return {
        myDiagram: null,
        show: false,
        flowName: '默认名称',
        nodeData: [] // 查看当前节点的数据
      }
    },
    activated() {
      setTimeout(_ => {
        this.$bridge.callHandler('navTitle', { title: '流程图' })
      }, 100)
    },
    mounted() {
      window.t = this
      const self = this
      var $ = go.GraphObject.make
      var myDiagram

      const data = {
        'class': 'go.GraphLinksModel',
        'linkFromPortIdProperty': 'fromPort',
        'linkToPortIdProperty': 'toPort',
        'nodeDataArray': [
        ],
        'linkDataArray': [
        ]
      }
      self.$axios({
         url: self.$common.basePath + 'aatp5/public/index.php/document/Document/index',
        method: 'POST',
        data: {
          id: ( self.$route.query.isnew == 'new' ? '-1' : self.$route.query.id ),
          tplid: self.$route.query.id,
          list: 1,
          type: self.$route.query.type, // 1:公文 2:流程
        }
      }).then(res => {
        data.nodeDataArray = res.data.nodeDataArray.map(item => {
          delete item.loc
          return item
        })

        data.linkDataArray = res.data.linkDataArray.map(item => {
          if(true) {
            delete item.fromPort
            delete item.toPort
          }
          return item 
        })
        createChart()
      }).catch(err => {
        console.log(err)
        self.$toast('接口调用错误')
      })
      function createChart () {
        myDiagram = $(go.Diagram,
          'myDiagramDiv',
          {
            'toolManager.mouseWheelBehavior': go.ToolManager.WheelZoom,
            'padding': new go.Margin(200,200,200,200),
            // 'grid.visible': true,
            // 'grid.gridCellSize': new go.Size(200, 200),
            // initialContentAlignment: new go.Spot(0, 0),
            allowGroup: false,
            initialAutoScale: go.Diagram.Uniform,
            layout: $(go.TreeLayout,
              { 
                layerSpacing: 200,
                portSpot: go.Spot.AllSides,
                childPortSpot: go.Spot.AllSides,
                layerStyle: go.TreeLayout.LayerSiblings,
                nodeSpacing: 200,
                angle: 0
              }
            )
          }
        )
        function nodeStyle() {
          return [
            // The Node.location comes from the 'loc' property of the node data,
            // converted by the Point.parse static method.
            // If the Node.location is changed, it updates the 'loc' property of the node data,
            // converting back using the Point.stringify static method.
            // new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
            {
            // the Node.location is at the center of each node
              locationSpot: go.Spot.Center
            }
          ]
        }

        function textStyle() {
          return {
            font: 'bold 13pt Lato, Helvetica, Arial, sans-serif',
            stroke: '#fff'
          }
        }

        function nodeSelectionChanged(node) {
          if(node.data.category == 'Start' || node.data.category == 'End') {
            node.isSelected = false
            return false
          }
          if (node.isSelected) {
            // 组装HTML 并渲染在合适的位置
            var left = window.pageX // left值
            var top = window.pageY // top值
            if(left + 400 > window.innerWidth) {
                left = left - 400
            }
            if(top + 250 > window.innerHeight) {
                top =  top - 250
            }
            if(node.data.nodeData) {
                self.nodeData = node.data.nodeData
                self.flowName = node.data.flowname
                self.nodeData.forEach(item => {
                  let perText = ''
                  switch(item.pertype) {
                    case '0':
                      perText = '等待审批';
                      break;
                    case '1':
                      perText = '同意';
                      break;
                    case '2':
                      perText = '拒绝';
                      break;
                    case '3':
                      perText = '退回';
                      break;
                    case '4':
                      perText = '等待审批';
                      break;
                    case '5':
                      perText = '结束';
                      break;
                    case '6':
                      perText = '委托';
                      break;
                    case '7':
                      perText = '挂起';
                      break;
                    case '8':
                      perText = '会签';
                      break;
                    case '9':
                      perText = '无需审批';
                      break;
                    default:
                      perText = '未定义的状态'
                      break;
                  }
                  item.perText = perText
                })
                console.log(self.nodeData)
                self.show = true
            } else {
              self.$toast('当前步骤暂未进行');
            }
            myDiagram.clearSelection()
          }
        }
        myDiagram.nodeTemplateMap.add('', // the default category
          $(go.Node, 'Table', nodeStyle(),
            { 
              movable: false,
              selectionChanged: nodeSelectionChanged
            },
            // the main object is a Panel that surrounds a TextBlock with a rectangular Shape
            $(go.Panel, 'Auto',
              $(go.Shape, 'RoundedRectangle',
                { strokeWidth: 3.5 },
                new go.Binding('figure', 'figure'),
                new go.Binding('stroke', '', function(node) { return node.data.color ? node.data.color : '#F5A703' }).ofObject(),
                new go.Binding('fill', '', function(node) { return node.data.color ? node.data.color : '#F5A703' }).ofObject()),
              $(go.TextBlock, textStyle(),
                {
                  textAlign: 'center',
                  margin: new go.Margin(50, 50, 50, 50),
                  wrap: go.TextBlock.WrapDesiredSize,
                  stroke: '#fff',
                  editable: false
                },
                new go.Binding('text').makeTwoWay())
            ),
          )
        )

        myDiagram.nodeTemplateMap.add('Conditional',
          $(go.Node, 'Table', nodeStyle(),
            // the main object is a Panel that surrounds a TextBlock with a rectangular Shape
            {
              movable: false,
              selectionChanged: nodeSelectionChanged
            },
            $(go.Panel, 'Auto',
              $(go.Shape, 'RoundedRectangle',
                { strokeWidth: 3.5 },
                new go.Binding('figure', 'figure'),
                new go.Binding('stroke', '', function(node) { return node.data.color ? node.data.color : '#F5A703' }).ofObject(),
                new go.Binding('fill', '', function(node) { return node.data.color ? node.data.color : '#F5A703' }).ofObject()),
              $(go.TextBlock, textStyle(),
                {
                  textAlign: 'center',
                  margin: new go.Margin(50, 50, 50, 50),
                  wrap: go.TextBlock.WrapDesiredSize,
                  stroke: '#fff',
                  editable: false
                },
                new go.Binding('text').makeTwoWay())
            ),
          )
        )

        myDiagram.nodeTemplateMap.add('Start',
          $(go.Node, 'Table', nodeStyle(),
            { 
              movable: false,
              selectionChanged: nodeSelectionChanged
            },
            $(go.Panel, 'Spot',
              $(go.Shape, 'Ellipse',
                { strokeWidth: 3.5 },
                new go.Binding('figure', 'figure'),
                new go.Binding('stroke', '', function(node) { return node.data.color ? node.data.color : '#F5A703' }).ofObject(),
                new go.Binding('fill', '', function(node) { return node.data.color ? node.data.color : '#F5A703' }).ofObject()),
              $(go.TextBlock, 'Start', textStyle(),
                new go.Binding('text'))
            ),
          )
        )

        myDiagram.nodeTemplateMap.add('End',
          $(go.Node, 'Table', nodeStyle(),
            { 
              movable: false,
              selectionChanged: nodeSelectionChanged
            },
            $(go.Panel, 'Spot',
              $(go.Shape, 'Ellipse',
                { strokeWidth: 3.5 },
                new go.Binding('figure', 'figure'),
                new go.Binding('stroke', '', function(node) { return node.data.color ? node.data.color : '#F5A703' }).ofObject(),
                new go.Binding('fill', '', function(node) { return node.data.color ? node.data.color : '#F5A703' }).ofObject()),
              $(go.TextBlock, 'End', textStyle(),
                new go.Binding('text'))
            ),
          )
        )

        // 重写默认的link
        myDiagram.linkTemplate = $(go.Link,
          { 
            adjusting: go.Link.End,
            routing: go.Link.AvoidsNodes,
            curve: go.Link.JumpGap,
            corner: 5,
            relinkableFrom: false,
            relinkableTo: false,
            reshapable: false,
            resegmentable: false,
            reshapable: false,
            zOrder: 1,
            selectionChanged: function(link) {
              if(link.isSelected) {
                if(link.data.reset == 1) {
                  // 拉高层级
                  myDiagram.model.setDataProperty(myDiagram.findLinkForKey(link.data.fid), 'zOrder', 30 + (new Date().getTime() / 100000000))
                  link.findObject('LABEL').visible = true
                }
              } else {
                link.findObject('LABEL').visible = false
              }
            },
            mouseEnter: function(e, link) {
                link.findObject('HIGHLIGHT').stroke = 'rgba(30,144,255,0.2)'
              },
            mouseLeave: function(e, link) { link.findObject('HIGHLIGHT').stroke = 'transparent' },
          },
          new go.Binding('points').makeTwoWay(),
          $(go.Shape, // the highlight shape, normally transparent
            { 
              isPanelMain: true, 
              strokeWidth: 8, 
              stroke: 'transparent', 
              name: 'HIGHLIGHT' 
            }
          ),
          $(go.Shape, // the PATH
            { isPanelMain: true, stroke: "#5f5f5f", strokeWidth: 2 },
            new go.Binding('stroke', 'isSelected',
              function(isSelected, shape) {
                return isSelected ? '#1e90ff' : (shape.part.data.active ? '#ff0000' : '#5f5f5f');
              }).ofObject(),
            new go.Binding('stroke', 'active',
              function(active) { return active ? '#ff0000' : '#5f5f5f'; })
          ),
          $(go.Shape, // the arrowhead
            { toArrow: 'standard', strokeWidth: 2, stroke: '#5f5f5f', fill: '#fff' },
            new go.Binding('stroke', 'isSelected',
              function(isSelected, shape) {
                return isSelected ? '#1e90ff' : (shape.part.data.active ? '#ff0000' : '#5f5f5f');
              }).ofObject(),
            new go.Binding('stroke', 'active',
              function(active) { return active ? '#ff0000' : '#5f5f5f'; })
          ),
          $(go.Panel, 'Auto', // the link label, normally not visible
            { 
              visible: false,
              name: 'LABEL',
              scale: 1.2,
            },
            // new go.Binding('visible', function(link) {return link.reset == 1 ? true : false }).makeTwoWay(),
            $(go.Shape, 'RoundedRectangle', // the label shape
              { fill: '#1e90ff', strokeWidth: 8, stroke: '#1e90ff'}),
            $(go.TextBlock, '默认标题', // the label
              {
                textAlign: 'center',
                font: '10pt helvetica, arial, sans-serif',
                stroke: '#fff',
                editable: false
              },
              new go.Binding('text', function(link) { return link.title || '默认内容' }).makeTwoWay())
          ),
        );
        // myDiagram.linkTemplate =
        //   $(go.Link, // 全局替换
        //     {
        //       routing: go.Link.AvoidsNodes, // 避开节点
        //       curve: go.Link.JumpOver, // 创建JumpOver跨越圆弧
        //       corner: 15,
        //       relinkableFrom: false,
        //       relinkableTo: false,
        //       reshapable: false,
        //       resegmentable: false,
        //       zOrder: 1,
        //       name: 'LINK',
        //       // mouse-overs subtly highlight links:
        //       mouseEnter: function(e, link) {
        //         link.findObject('HIGHLIGHT').stroke = 'rgba(30,144,255,0.2)'
        //       },
        //       selectionChanged: function(link) {
        //         link.findObject('LINK').zOrder = 30
        //       },
        //       mouseLeave: function(e, link) { link.findObject('HIGHLIGHT').stroke = 'transparent' },
        //       selectionAdorned: false
        //     },
        //     new go.Binding('points').makeTwoWay(),
        //     $(go.Shape, // the highlight shape, normally transparent
        //       { 
        //         isPanelMain: true, 
        //         strokeWidth: 8, 
        //         stroke: 'transparent', 
        //         name: 'HIGHLIGHT' 
        //       }
        //     ),
        //     $(go.Shape, // the link path shape
        //       { 
        //         isPanelMain: true, 
        //         stroke: '#5f5f5f',
        //         strokeWidth: 2,
        //         name: 'PATH'
        //       },
        //       new go.Binding('stroke', '', function(link) { return link.data.active ? 'red' : '#5f5f5f' }).ofObject(),
        //       new go.Binding('stroke', 'isSelected', function(sel, link) {
        //         return sel ? 'dodgerblue' : link.stroke }).ofObject()),
        //     $(go.Shape, // the arrowhead
        //       { toArrow: 'standard', strokeWidth: 0, stroke: '#5f5f5f' },
        //       new go.Binding('fill', '', function(link) { return link.data.active ? 'red' : '#5f5f5f' }).ofObject(),
        //       new go.Binding('fill', 'isSelected', function(sel, link) {
        //         return sel ? 'dodgerblue' : ( link.data.active ? 'red' : link.stroke ) }).ofObject(),
        //       ),
        //     $(go.Panel, 'Auto', // the link label, normally not visible
        //       { visible: false, name: 'LABEL', segmentIndex: 2, segmentFraction: 0.5 },
        //       new go.Binding('visible', function(link) {return link.from > link.to ? true : false }).makeTwoWay(),
        //       $(go.Shape, 'RoundedRectangle', // the label shape
        //         { fill: '#F8F8F8', strokeWidth: 0 }),
        //       $(go.TextBlock, 'Yes', // the label
        //         {
        //           textAlign: 'center',
        //           font: '10pt helvetica, arial, sans-serif',
        //           stroke: '#333333',
        //           editable: true
        //         },
        //         new go.Binding('text').makeTwoWay())
        //     )
        //   )

        // Make link labels visible if coming out of a 'conditional' node.
        // This listener is called by the 'LinkDrawn' and 'LinkRelinked' DiagramEvents.
        // function showLinkLabel(e) {
        //   var label = e.subject.findObject('LABEL');
        //   if (label !== null) label.visible = (e.subject.fromNode.data.category === 'Conditional');
        // }

        // temporary links used by LinkingTool and RelinkingTool are also orthogonal:
        // myDiagram.toolManager.linkingTool.temporaryLink.routing = go.Link.Orthogonal
        // myDiagram.toolManager.relinkingTool.temporaryLink.routing = go.Link.Orthogonal
        // myDiagram.commandHandler.zoomToFit() // 在方法中调用
        myDiagram.model = go.Model.fromJson(JSON.stringify(data))
        myDiagram.model.linkKeyProperty = 'fid'
        myDiagram.model.linkLabelKeysProperty = 'title'
      }
    },
    methods: {
      /**
       * @description: 根据精度误差过滤 (一维数组 / 对象数组)中的近似值
       * @param {String} ary 源数据
       * @param {Number} pre 误差范围, 小于此范围的数相邻数据会被过滤
       * @param {String} type 数据类型 default一维数组 object对象数组
       * @param {Array}  keyList 比对的键名数组, 在指定type != default 后必填
       * @return: [] 处理后的数据
       */
      resetAryByPrecision(ary, pre, type = 'default', keyList) {
        const array = ['10.1', '11.2', '21.3', '10.0', '1.6', '1.1', '1.3']
        const objectArray = [{ lan: '10.1', lat: '10.2' }, { lan: '10.3', lat: '10.6' }, { lan: '11.1', lat: '10.2' }, { lan: '13.1', lat: '13.2' }]
        let result = []
        try {
          if (type === 'default') {
            result = array.filter((item, index, array) => {
              if (index === 0) { // 排除首位
                return true
              } else {
                return Math.abs(item - array[index - 1]) > pre
              }
            })
          } else if (!keyList && !Array.isArray(keyList)) {
            throw new Error('params \'keyList\' error!')
          }
        } catch (err) {
          console.error(err)
        }
        return result
      },
      print() {
        var svgWindow = window.open('', '_blank', 'toolbar=yes, location=yes, directories=no, status=no, menubar=yes, scrollbars=yes, resizable=no, copyhistory=yes, width=1000, height=800, titlebar=no')
        if (!svgWindow) return // failure to open a new Window
        var svg = this.myDiagram.makeImage({ scale: 1.0 })
        var style = document.createElement('style')
        style.innerHTML = 'img {width: 100vw;}'
        svgWindow.document.body.appendChild(style)
        svgWindow.document.body.appendChild(svg)
        setTimeout(function() { svgWindow.print() }, 1)
      },
      saveImg() {
        // dataurl为去掉了头的base64格式编码
        function dataURLtoBlob(dataurl) {
          // 使用atob方法解码base64
          var raw = window.atob(dataurl)
          // 创建一个存储解码后数据的数组
          var uInt8Array = new Uint8Array(raw.length)
          // blob只能接收二进制编码，需要讲base64转为二进制再塞进去
          for (var i = 0; i < raw.length; ++i) {
            uInt8Array[i] = raw.charCodeAt(i)
          }
          // 这里给了一个返回值，在别的方法掉用传入base64编码就可以得到转化后的blob
          return new Blob([uInt8Array], { type: '' })
        }
        var svg = this.myDiagram.makeImage({ scale: 1.0 })
        const blob = dataURLtoBlob(svg.src.substr(svg.src.indexOf('base64') + 7))
        var a = document.createElement('a')
        a.setAttribute('href', URL.createObjectURL(blob))
        a.setAttribute('download', '流程图.png')
        a.click()
      }
    }
  }
</script>


<style type="text/css" lang="less">
  .van-popup {
    width: 65vw;
    max-height: 80vh;
    padding: 0 25px 0 25px;
    border-radius: 8px;
    p {
      font-size: 16px;
      font-weight: normal;
      color: #333;
    }
  }
</style>
